04.MyBatis-Spring

MyBatis-Spring

什么是 MyBatis-Spring?

Page not found · GitHub Pages

MyBatis-Spring 使用

<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>2.0.6</version>
</dependency>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
</bean>

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
public class UserDaoImpl implements UserDao {

  private SqlSession sqlSession;

  public void setSqlSession(SqlSession sqlSession) {
    this.sqlSession = sqlSession;
  }

  public User getUser(String userId) {
    return sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSession" ref="sqlSession" />
</bean>

MyBatis-Spring 整合

普通整合

package me.hacket.spring.model;

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
package me.hacket.mapper;

import me.hacket.spring.model.User;

import java.util.List;

public interface UserMapper {

    // select
    //查询所有用户
    List<User> selectUser();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--导入properties文件-->
    <properties resource="db.properties"/>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--下划线驼峰自动转换-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--开启全局缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias type="me.hacket.spring.model.User" alias="User"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="me.hacket.mapper.UserMapper">
    <select id="selectUser" resultType="me.hacket.spring.model.User">
        select *
        from user
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 通过注解的方式注入 -->
    <context:annotation-config/>

    <!-- DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid -->
    <!-- 我们这里使用spring是供JDBC:org.springframework.jdbc.datasource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url"
                  value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;serverTimezone=UTC&amp;characterEncoding=UTF-8&amp;allowPublicKeyRetrieval=false"/>
        <property name="username" value="root"/>
        <property name="password" value="zfs1314520"/>
    </bean>

    <!--配置SqlSessionFactory,关联MyBatis,spring_beans_mybatis.xml文件-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 绑定mybatis配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:spring_user_mapper.xml"/>
    </bean>

    <!--注册sqlSessionTemplate,关联sqlSessionFactory;spring_beans_mybatis.xml文件-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能使用构造器注入sqlSessionFactory,因为它没有set方法 -->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
</beans>
package me.hacket.mapper;

import me.hacket.spring.model.User;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class UserMapperImpl implements UserMapper {
    // 我们的所有操作,都使用sqlSession来执行,在原来,现在都使用SqlSessionTemplate;
    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public List<User> selectUser() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="spring_dao.xml"/>

    <bean id="userMapper" class="me.hacket.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>
</beans>
@Test
public void selectUser2() throws IOException {
	ApplicationContext context = new ClassPathXmlApplicationContext("spring_application_context.xml");
	UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
	for (User user : userMapper.selectUser()) {
		System.out.println(user);
	}
}

SqlSessionDaoSupport

mybatis-spring1.2.3 版以上的才有这个。

dao 继承 Support 类,直接利用 getSqlSession() 获得,然后直接注入 SqlSessionFactory。比起方式 1,不需要管理 SqlSessionTemplate , 而且对事务的支持更加友好。可跟踪源码查看

import com.github.subei.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
    public List<User> selectUser() {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="spring_dao.xml"/>

    <bean id="userMapper2" class="me.hacket.mapper.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

</beans>
@Test
public void selectUser3() throws IOException {
	ApplicationContext context = new ClassPathXmlApplicationContext("spring_application_context.xml");
	UserMapperImpl2 userMapper = context.getBean("userMapper2", UserMapperImpl2.class);
	for (User user : userMapper.selectUser()) {
		System.out.println(user);
	}
}

总结 : 整合到 Spring 以后可以完全不要 mybatis 的配置文件,除了这些方式可以实现整合之外,还可以使用注解来实现。

Spring 事务

Spring 在不同的事务管理 API 之上定义了一个抽象层,使得开发人员不必了解底层的事务管理 API 就可以使用 Spring 的事务管理机制。Spring 支持编程式事务管理声明式的事务管理

编程式事务管理

声明式事务管理==(交由容器管理事务)

声明式事务管理

 <!-- 配置声明式事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"/>
</bean>
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns:context="http://www.springframework.org/schema/context"  
       xmlns:tx="http://www.springframework.org/schema/tx"  
       xmlns:aop="http://www.springframework.org/schema/aop"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
        https://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        https://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop.xsd        http://www.springframework.org/schema/tx        http://www.springframework.org/schema/tx/spring-tx.xsd">
<beans>
<!-- 结合AOP实现事物的织入 -->
<!-- 配置事务的通知: -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
		<!-- 配置哪些方法使用什么样的事务,配置事务的传播特性 -->
		<tx:method name="add" propagation="REQUIRED"/>
		<tx:method name="delete" propagation="REQUIRED"/>
		<tx:method name="update" propagation="REQUIRED"/>
		<tx:method name="search*" propagation="REQUIRED"/>
		<tx:method name="get" read-only="true"/>
		<tx:method name="*" propagation="REQUIRED"/>
	</tx:attributes>
</tx:advice>
<!-- 配置事务的切入 -->
<aop:config>
	<aop:pointcut id="txPointcut" expression="execution(* me.hacket.mapper.*.*(..))"/>
	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

spring 事务传播特性

事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring 支持 7 种事务传播行为:

Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。

为什么需要配置事务 ?